(*DONT_TOUCH = "TRUE"*)
module IIR_top #(
    parameter datin_width = 16,
    parameter daout_width = 16,
    parameter mux_num = 1536
) (
    clk,
    rst_n,
    start,

    datin_bram_r_data,
    datin_bram_r_en,
    datin_bram_r_addr,

    daout_bram_w_data,
    daout_bram_w_we,
    daout_bram_w_en,
    daout_bram_w_addr,

    update_flag
);
    
input clk;
input rst_n;
input start; //2khz

input [datin_width-1 : 0] datin_bram_r_data;
output datin_bram_r_en;
output [clogb2(mux_num)-1 : 0] datin_bram_r_addr;

output [daout_width-1 : 0] daout_bram_w_data;
output daout_bram_w_we;
output daout_bram_w_en;
output [clogb2(mux_num)-1 : 0] daout_bram_w_addr;
output update_flag;

wire busy0;
wire busy1;
wire busy2;
wire busy3;

wire next_en_flag_0;// 200hz
wire next_en_flag_1;// 20hz
//wire next_en_flag_2;// 2hz
//wire next_en_flag_3; // 最后输出
wire [datin_width-1 : 0] temp0_bram_r_data;
wire [clogb2(mux_num)-1 : 0] temp0_bram_r_addr;
wire [datin_width-1 : 0] temp1_bram_r_data;
wire [clogb2(mux_num)-1 : 0] temp1_bram_r_addr;
wire [datin_width-1 : 0] temp2_bram_r_data;
wire [clogb2(mux_num)-1 : 0] temp2_bram_r_addr;
wire [datin_width-1 : 0] temp0_bram_w_data;
wire [clogb2(mux_num)-1 : 0] temp0_bram_w_addr;
wire [datin_width-1 : 0] temp1_bram_w_data;
wire [clogb2(mux_num)-1 : 0] temp1_bram_w_addr;
wire [datin_width-1 : 0] temp2_bram_w_data;
wire [clogb2(mux_num)-1 : 0] temp2_bram_w_addr;

wire temp0_bram_w_en;
wire temp0_bram_r_en;

assign update_flag = next_en_flag_1; //最后一级的输入为刷新

IIR_2_core_pipline u_IIR_2_core_pipline_0(
    .clk(clk),
    .rst_n(rst_n),
    .en_flag(start),
    .busy(busy0),
    .next_en_flag(next_en_flag_0),

    .datin_bram_r_data(datin_bram_r_data),//datin_BRAM读数据线
    .datin_bram_r_en(datin_bram_r_en),//datin_BRAM使能信号
    .datin_bram_r_addr(datin_bram_r_addr), //datin_BRAM读地址线

    .daout_bram_w_data(temp0_bram_w_data),
    .daout_bram_w_we(temp0_bram_w_we),
    .daout_bram_w_en(temp0_bram_w_en),
    .daout_bram_w_addr(temp0_bram_w_addr)
);

temp_bram u_temp0_bram (
    .clka(clk),    // input wire clka 写
    .ena(temp0_bram_w_en),      // input wire ena
    .wea(temp0_bram_w_we),      // input wire [0 : 0] wea
    .addra(temp0_bram_w_addr),  // input wire [10 : 0] addra
    .dina(temp0_bram_w_data),    // input wire [95 : 0] dina

    .clkb(clk),    // input wire clkb 读
    .enb(temp0_bram_r_en),      // input wire enb
    .addrb(temp0_bram_r_addr),  // input wire [10 : 0] addrb
    .doutb(temp0_bram_r_data)  // output wire [95 : 0] doutb
);

IIR_2_core_pipline  u_IIR_2_core_pipline_1(
    .clk(clk),
    .rst_n(rst_n),
    .en_flag(next_en_flag_0),
    .busy(busy1),
    .next_en_flag(next_en_flag_1),

    .datin_bram_r_data(temp0_bram_r_data),//datin_BRAM读数据线
    .datin_bram_r_en(temp0_bram_r_en),//datin_BRAM使能信号
    .datin_bram_r_addr(temp0_bram_r_addr), //datin_BRAM读地址线

    .daout_bram_w_data(temp1_bram_w_data),
    .daout_bram_w_we(temp1_bram_w_we),
    .daout_bram_w_en(temp1_bram_w_en),
    .daout_bram_w_addr(temp1_bram_w_addr)
);

temp_bram u_temp1_bram (
    .clka(clk),    // input wire clka 写
    .ena(temp1_bram_w_en),      // input wire ena
    .wea(temp1_bram_w_we),      // input wire [0 : 0] wea
    .addra(temp1_bram_w_addr),  // input wire [10 : 0] addra
    .dina(temp1_bram_w_data),    // input wire [95 : 0] dina

    .clkb(clk),    // input wire clkb 读
    .enb(temp1_bram_r_en),      // input wire enb
    .addrb(temp1_bram_r_addr),  // input wire [10 : 0] addrb
    .doutb(temp1_bram_r_data)  // output wire [95 : 0] doutb
);

IIR_2_core_pipline u_IIR_2_core_pipline_2(
    .clk(clk),
    .rst_n(rst_n),
    .en_flag(next_en_flag_1),
    .busy(busy2),
    .next_en_flag(next_en_flag_2),

    .datin_bram_r_data(temp1_bram_r_data),//datin_BRAM读数据线
    .datin_bram_r_en(temp1_bram_r_en),//datin_BRAM使能信号
    .datin_bram_r_addr(temp1_bram_r_addr), //datin_BRAM读地址线

    .daout_bram_w_data(daout_bram_w_data),
    .daout_bram_w_we(daout_bram_w_we),
    .daout_bram_w_en(daout_bram_w_en),
    .daout_bram_w_addr(daout_bram_w_addr)
    // .daout_bram_w_data(temp2_bram_w_data),
    // .daout_bram_w_we(temp2_bram_w_we),
    // .daout_bram_w_en(temp2_bram_w_en),
    // .daout_bram_w_addr(temp2_bram_w_addr)
);

// temp_bram u_temp2_bram (
//     .clka(clk),    // input wire clka 写
//     .ena(temp2_bram_w_en),      // input wire ena
//     .wea(temp2_bram_w_we),      // input wire [0 : 0] wea
//     .addra(temp2_bram_w_addr),  // input wire [10 : 0] addra
//     .dina(temp2_bram_w_data),    // input wire [95 : 0] dina

//     .clkb(clk),    // input wire clkb 读
//     .enb(temp2_bram_r_en),      // input wire enb
//     .addrb(temp2_bram_r_addr),  // input wire [10 : 0] addrb
//     .doutb(temp2_bram_r_data)  // output wire [95 : 0] doutb
// );

// IIR_2_core_pipline #(
//     .datin_width(datin_width),
//     .daout_width(daout_width),
//     .index_bit(clogb2(mux_num)),
//     .index_max(mux_num)
// ) u_IIR_2_core_pipline_3(
//     .clk(clk),
//     .rst_n(rst_n),
//     .en_flag(next_en_flag_2),
//     .busy(busy3),
//     .next_en_flag(next_en_flag_3),

//     .datin_bram_r_data(temp2_bram_r_data),//datin_BRAM读数据线
//     .datin_bram_r_en(temp2_bram_r_en),//datin_BRAM使能信号
//     .datin_bram_r_addr(temp2_bram_r_addr), //datin_BRAM读地址线

//     .daout_bram_w_data(),
//     .daout_bram_w_we(),
//     .daout_bram_w_en(),
//     .daout_bram_w_addr()
//     // .daout_bram_w_data(daout_bram_w_data),
//     // .daout_bram_w_we(daout_bram_w_we),
//     // .daout_bram_w_en(daout_bram_w_en),
//     // .daout_bram_w_addr(daout_bram_w_addr)
// );

function integer clogb2(input integer depth);
    integer tmp;
    begin
        tmp = depth;
        for (clogb2 = 0; tmp > 0; clogb2 = clogb2 + 1) 
            tmp = tmp >> 1;                          
    end
endfunction
endmodule